package com.example.ivos.audit.service.impl;

import com.example.ivos.application.mapper.ApplicationMapper;
import com.example.ivos.application.pojo.dto.ApplicationQuery;
import com.example.ivos.application.pojo.entity.Application;
import com.example.ivos.application.pojo.vo.ApplicationVO;
import com.example.ivos.application.service.ApplicationService;
import com.example.ivos.audit.mapper.AuditMapper;
import com.example.ivos.audit.pojo.dto.AuditParam;
import com.example.ivos.audit.pojo.dto.AuditQuery;
import com.example.ivos.audit.pojo.entity.Audit;
import com.example.ivos.audit.pojo.vo.AuditVO;
import com.example.ivos.audit.service.AuditService;
import com.example.ivos.base.enums.ApplicationStatusEnum;
import com.example.ivos.base.enums.AuditStatusEnum;
import com.example.ivos.user.mapper.UserMapper;
import com.example.ivos.user.pojo.dto.UserQuery;
import com.example.ivos.user.pojo.entity.User;
import com.example.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Transactional
@Service
@Slf4j
public class AuditServiceImpl implements AuditService {

    @Autowired
    private AuditMapper auditMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ApplicationMapper applicationMapper;

    @Override
    public void insertAudit(Application application) {
        log.debug("添加审批单业务:application={}",application);
        List<Long> userIdList=application.getAuditUserIdList();
        for(int i=0;i<userIdList.size();i++){
            Audit audit=new Audit();
            audit.setApplicationId(application.getId());
            audit.setAuditUserId(userIdList.get(i));
            audit.setAuditSort(i);
            if(i==0){
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            }
            else{
                audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
            }
            audit.setCreateTime(new Date());
            auditMapper.insert(audit);
        }

    }

    @Override
    public List<AuditVO> selectAudit(AuditQuery auditQuery) {
        log.debug("查询审批单业务:auditQuery={}",auditQuery);
        Audit audit=new Audit();
        BeanUtils.copyProperties(auditQuery,audit);
        List<AuditVO> auditVOList=auditMapper.selectAudit(audit);
        for(int i=0;i<auditVOList.size();i++){
            AuditVO auditVO=auditVOList.get(i);
            assignAuditUserList(auditVO);
        }
        return auditVOList;
    }

    private void assignAuditUserList(AuditVO auditVO){
        List<Long> auditUserIdList=new ArrayList<>();
        List<String> auditUsernameList=new ArrayList<>();
        Audit audit=new Audit();
        audit.setApplicationId(auditVO.getApplicationId());
        List<AuditVO> auditVOS = auditMapper.selectAudit(audit);
        for (int i=0;i<auditVOS.size();i++){
            auditUserIdList.add(auditVOS.get(i).getAuditUserId());
            UserQuery userQuery=new UserQuery();
            userQuery.setId(auditVOS.get(i).getAuditUserId());
            List<UserVO> userVOS = userMapper.UserSelect(userQuery);
            auditUsernameList.add(userVOS.get(0).getUsername());
        }
        StringJoiner stringJoiner=new StringJoiner(",");
        for(String username:auditUsernameList){
            stringJoiner.add(username);
        }
        auditVO.setAuditUserIdList(auditUserIdList);
        auditVO.setAuditUsernameList(stringJoiner.toString());
    }

    @Override
    public void removeAudit(Long id) {
        log.debug("删除审批单业务:id={}",id);
        auditMapper.delAuditByApplicationId(id);
    }

    @Override
    public void update(AuditParam auditParam) {
        log.debug("审批业务:auditParam={}",auditParam);
        Audit audit=new Audit();
        BeanUtils.copyProperties(auditParam,audit);
        audit.setUpdateTime(new Date());
        Application application=new Application();
        application.setId(audit.getApplicationId());
        application.setUpdateTime(new Date());
        //判断前端传过来的审批参数是通过还是驳回，分别针对不同的审批结果做下一步处理
        if(audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())){ //通过
            //更新当前的这条审批单
            auditMapper.update(audit);
            /*继续查其他审批单：其他审批单与当前审批单单批的是同一个申请单*/
            AuditQuery auditQuery=new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            Integer count=auditMapper.selectRestAuditCount(auditQuery);
            if(count>0){
                //如果还有未审批的审批单，则更新下一个审批单
               auditQuery.setAuditSort(audit.getAuditSort()+1);
               Audit nextAudit=new Audit();
               BeanUtils.copyProperties(auditQuery,nextAudit);
               List<AuditVO> auditVOS = auditMapper.selectAudit(nextAudit);
               if(auditVOS.size()>0&&auditVOS!=null){
                   Audit audit1=new Audit();
                   audit1.setId(auditVOS.get(0).getId());
                   audit1.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                   auditMapper.update(audit1);
               }
                //设置当前申请单的状态为"审核中",更新申请单数据
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
            }else{
                //如果当前审批单是最后一个审批单，则更新申请单状态
                application.setStatus(ApplicationStatusEnum.AUDITED.getCode());

            }
            applicationMapper.update(application);
        }else{//驳回
            auditMapper.update(audit);
            Audit audit2=new Audit();
            audit2.setApplicationId(audit.getApplicationId());
            List<AuditVO> auditVOS = auditMapper.selectAudit(audit2);
            if(auditVOS.size()>0&&auditVOS!=null){
               for(int i=0;i<auditVOS.size();i++){
                   AuditVO auditVO=auditVOS.get(i);
                   if(auditVO.getAuditStatus().equals(AuditStatusEnum.MY_PENDING.getCode())||auditVO.getAuditStatus().equals(AuditStatusEnum.PENDING.getCode())){
                       auditMapper.delete(auditVO.getId());
                   }
               }
            }
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditParam.getRejectReason());
            applicationMapper.update(application);
        }

    }
}
